/**
 * @file imagenppm.h
 * @brief T.D.A. Imagen PPM
 *
 * @author Antonio Ruano Cuesta
 * @date Mayo-06
 */
 
 /* Copyright 2010 Antonio Ruano Cuesta
 *
 * This program is free software: you can redistribute it and/or modify it under 
 * the terms of the GNU General Public License as published by the Free Software 
 * Foundation, either version 3 of the License, or (at your option) any later 
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with 
 * this program. If not, see <http://www.gnu.org/licenses/>
*/

#ifndef IMAGENPPM
#define IMAGENPPM

/** Tipo byte (pixeles de la imagen) declarado como unsigned char ya que el rango de valores 
  * necesario es de 0 a 255.
  */
typedef unsigned char byte;

/**
 * La clase imagen PPM es muy similar a la clase imagen PGM, tan solo varia en un detalle: 
 * cada imagen de tipo PPM almacena 3 valores para un pixel, por tanto en este caso, 
 * necesario crear una estructura a la que llamaré "PPM" dentro de la cual habrá 3 campos, 
 * R,G y B, de tipo unsigned char ya que cada uno solo puede tener un valor comprendido entre 
 * 0 y 255.
 * La estructura de datos que soportará la imagen será un vector dinámico de estructuras de	
 * este tipo.
 */
class ImagenPPM{

  private:

	/**
      * @page repConjunto Rep del TDA Imagen PPM
      *
      * @section invConjunto Invariante de la representación
      *
      * El invariante es \e rep.filas>0 y rep.cols>0      
    */

	struct PPM
	{
		byte R;
		byte G;
		byte B;
	};

    int filas; /**Filas de las que consta la imagen*/
    
	int cols; /**Columnas de las que consta la imagen*/
    
	PPM **imgPPM; /**Puntero a puntero encargado de la reserva de memoria */

  public:
		
	/**
     * @brief Constructor por defecto de la clase. Pone todos sus campos 
     * filas, cols e imgPPM a 0.
    */
    ImagenPPM();
		
	/**
     * @brief Constructor de la clase.
     * @param filas: número de filas de la imagen a crear.
     * @param cols: número de columnas de la imagen a crear.
     * @return crea una imagen con fil filas y col columnas, dejando sus elementos
     * con valores "basura".
     * @pre filas y cols mayores que 0.
    */	
    ImagenPPM(int filas, int cols);
		
	/**
     * @brief Constructor de copias de la clase.
     * @param im imagen de la que se va a hacer la copia.
    */
	ImagenPPM(const ImagenPPM &im);
		
	/**
     * @brief Destructor: libera la memoria reservada para la imagen PPM.
    */
	~ImagenPPM();
		
	/**
     * @brief Asigna una imagen PPM(im) a una variable del tipo Imagen PPM.
     * @param im imagen a asignar al objeto implícito.
	*/
	ImagenPPM& operator=(const ImagenPPM &im);

	/**
	 * @brief Función que consulta el número de filas.
	 * @return Devuelve el número de filas de las que consta una imagen PPM.
	*/
	int num_filasPPM() const;

	/**
	 * @brief Función que consulta el número de columnas.
	 * @return Devuelve el número de columnas de las que consta una imagen PPM.
	*/
	int num_columnasPPM() const;

	/**
	 * @brief Asigna un color a una determinada posición.
	 * @param fila: fila en la que se quiere insertar el color.
	 * @param col: columna en la que se quiere insertar el color.
	 * @param Re: nivel de color R que se quiere insertar en la posición.
	 * @param Gr: nivel de color G que se quiere insertar en la posición.
	 * @param Bl: nivel de color B que se quiere insertar en la posición.
	 * @pre 	0<=fila<num_filasPPM()
	 * 			0<=col<num_columnasPPM()
	 * 			0<=Re,Gr,Bl<=255
	*/
	void set_pixPPM(int fila, int col,byte Re, byte Gr, byte Bl);

	/**
	 * @brief Consulta el valor R de una determinada posición de la imagen.
	 * @param fila: fila a consultar.
	 * @param col: columna a consultar.
	 * @pre 	0<=fila<num_filasPPM()
	 * 			0<=col<num_columnasPPM()
	 * @return nivel de color R (devuelve unsigned char).
	*/
	byte get_pixR(int fila, int col) const;

	/**
	 * @brief Consulta el valor G de una determinada posición de la imagen.
	 * @param fila: fila a consultar.
	 * @param col: columna a consultar.
	 * @pre 	0<=fila<num_filasPPM()
	 * 			0<=col<num_columnasPPM()
	 * @return nivel de color G (devuelve unsigned char).
	*/
	byte get_pixG(int fila, int col) const;

	/**
	 * @brief Consulta el valor B de una determinada posición de la imagen.
	 * @param fila: fila a consultar.
	 * @param col: columna a consultar.
	 * @pre 	0<=fila<num_filasPPM()
	 * 			0<=col<num_columnasPPM()
	 * @return nivel de color B (devuelve unsigned char).
	*/
	byte get_pixB(int fila, int col) const;

	/**
 	* @brief Lee una imagen PPM de un fichero y almacena sus valores en el objeto de la clase. 
	* @param nombre: nombre del fichero a leer de disco.
	*/
	void InsertaImagenPPM(const char *nombre);

	/**
 	* @brief Guarda en disco la imagen PPM que se encuentra almacenada en el objeto de la 
	* clase.
 	* @param nombre: nombre del archivo a escribir en disco.
	* @return true si la imagen se ha guardado con éxito, false en caso contrario.
 	*/
	bool EscribeImagenPPM(const char *nombre);
};



#endif
